package main

import (
	"database/sql"
	"errors"
	"fmt"
	pb "ihos/ihos"
	"log"

	tm "github.com/golang/protobuf/ptypes/timestamp"
)

type menzhen_paiban struct {
	id             int32  //PK
	sequenceno     string //排班编码
	visitdate      int64  //就诊日期
	timecode       int32  //时间代码 上午1 下午2 晚上3
	starttime      int64  //排班开始时间
	endtime        int64  //排班结束时间
	deptcode       string //科室代码
	deptname       string //科室名称
	doctorsex      int32  //医生性别
	doctorname     string //医生名称
	doctorcode     string //医生代码
	titlecode      string //排班类型编码 主任门诊，副主任门诊
	visitprice     int32  //挂号费
	clinicprice    int32  //诊疗费
	otherprice     int32  //其他诊疗费
	clinicaddress  string //诊疗地址 骨科诊室二
	status         string //排班状态 出诊
	staffintroduce string //专家介绍
	registername   string //专家号/普通号/本院职工
	timescope      string //候诊时间范围
	timename       string //时间名称
	remark         string //备注
	hoscode        string //医院编码
	hosname        string //医院名称
	leixing        int32  //排班类型
}

func (w *menzhen_paiban) GetFromDB(id int32) error {
	sql := "SELECT id,sequenceno,visitdate,timecode,starttime,endtime,deptcode,deptname,doctorsex,doctorname,doctorcode,titlecode,visitprice,clinicprice,otherprice,clinicaddress,status,staffintroduce,registername,timescope,timename,remark,hoscode,hosname,leixing FROM menzhen_paiban WHERE id=$1"
	return DBConn.db.QueryRow(sql, id).Scan(&w.id, &w.sequenceno, &w.visitdate, &w.timecode, &w.starttime, &w.endtime, &w.deptcode, &w.deptname, &w.doctorsex, &w.doctorname, &w.doctorcode, &w.titlecode, &w.visitprice, &w.clinicprice, &w.otherprice, &w.clinicaddress, &w.status, &w.staffintroduce, &w.registername, &w.timescope, &w.timename, &w.remark, &w.hoscode, &w.hosname, &w.leixing)
}

func (w *menzhen_paiban) GetMenZhenPaiBanList() (pbs []*menzhen_paiban, err error) {
	// log.Println("GetMenZhenPaiBanList:", w.leixing)
	sqlStr := ""
	if w.id > 0 {
		// ID is specified
		sqlStr = "SELECT id,sequenceno,visitdate,timecode,starttime,endtime,deptcode,deptname,doctorsex,doctorname,doctorcode,titlecode,visitprice,clinicprice,otherprice,clinicaddress,status,staffintroduce,registername,timescope,timename,remark,hoscode,hosname,leixing FROM menzhen_paiban WHERE id=" + fmt.Sprint(w.id)
	} else {
		sqlStr = "SELECT id,sequenceno,visitdate,timecode,starttime,endtime,deptcode,deptname,doctorsex,doctorname,doctorcode,titlecode,visitprice,clinicprice,otherprice,clinicaddress,status,staffintroduce,registername,timescope,timename,remark,hoscode,hosname,leixing FROM menzhen_paiban"
		cond := make([]string, 0)
		if len(w.sequenceno) > 0 {
			cond = append(cond, "sequenceno='"+fmt.Sprint(w.sequenceno)+"'")
		}
		if w.starttime > 0 {
			cond = append(cond, "starttime<="+fmt.Sprint(w.starttime))
		}
		if w.endtime > 0 {
			cond = append(cond, "endtime>="+fmt.Sprint(w.endtime))
		}
		if len(w.hoscode) > 0 {
			cond = append(cond, "hoscode='"+w.hoscode+"'")
		}
		switch w.leixing {
		case 1: //全科，需要科室匹配
			if len(w.deptcode) == 0 {
				return nil, errors.New("Invalid parameter")
			}
			cond = append(cond, "deptcode='"+w.deptcode+"'")
		case 2: //专家，需要科室和医生都匹配
			if len(w.deptcode) == 0 || len(w.doctorcode) == 0 {
				return nil, errors.New("Invalid parameter")
			}
			cond = append(cond, "(deptcode='"+w.deptcode+"' AND doctorcode='"+w.doctorcode+"')")
		case 3: //全科，只要医院匹配即可
		}
		if len(w.titlecode) > 0 {
			cond = append(cond, "titlecode='"+w.titlecode+"'")
		}
		if len(w.status) > 0 {
			cond = append(cond, "status='"+w.status+"'")
		}
		if w.leixing > 0 {
			cond = append(cond, "leixing="+fmt.Sprint(w.leixing))
		}
		if len(cond) > 0 {
			sqlStr += " WHERE "
			sep := ""
			for _, v := range cond {
				sqlStr += sep + v
				sep = " AND "
			}
		}
		sqlStr += " ORDER BY id DESC"
	}
	// log.Println("GetMenZhenPaiBanList:", sqlStr)
	var rows *sql.Rows
	if rows, err = DBConn.db.Query(sqlStr); err != nil {
		log.Println(err)
		return nil, err
	}
	defer rows.Close()
	out := make([]*menzhen_paiban, 0)
	for rows.Next() {
		w := &menzhen_paiban{}
		if err = rows.Scan(&w.id, &w.sequenceno, &w.visitdate, &w.timecode, &w.starttime, &w.endtime, &w.deptcode, &w.deptname, &w.doctorsex, &w.doctorname, &w.doctorcode, &w.titlecode, &w.visitprice, &w.clinicprice, &w.otherprice, &w.clinicaddress, &w.status, &w.staffintroduce, &w.registername, &w.timescope, &w.timename, &w.remark, &w.hoscode, &w.hosname, &w.leixing); err != nil {
			log.Println(err)
			//return nil, err
		} else {
			out = append(out, w)
		}
	}
	return out, nil
}

func (w *menzhen_paiban) SaveToDB(id int32) error {
	sql := ""
	var err error
	if id > 0 { //update
		sql = "UPDATE menzhen_paiban SET sequenceno=$1,visitdate=$2,timecode=$3,starttime=$4,endtime=$5,deptcode=$6,deptname=$7,doctorsex=$8,doctorname=$9,doctorcode=$10,titlecode=$11,visitprice=$12,clinicprice=$13,otherprice=$14,clinicaddress=$15,status=$16,staffintroduce=$17,registername=$18,timescope=$19,timename=$20,remark=$21,hoscode=$22,hosname=$23,leixing=$24 where id=$25 RETURNING id"
		err = DBConn.db.QueryRow(sql, w.sequenceno, w.visitdate, w.timecode, w.starttime, w.endtime, w.deptcode, w.deptname, w.doctorsex, w.doctorname, w.doctorcode, w.titlecode, w.visitprice, w.clinicprice, w.otherprice, w.clinicaddress, w.status, w.staffintroduce, w.registername, w.timescope, w.timename, w.remark, w.hoscode, w.hosname, w.leixing, w.id).Scan(&w.id)
	} else { //insert
		sql = "INSERT INTO menzhen_paiban(sequenceno,visitdate,timecode,starttime,endtime,deptcode,deptname,doctorsex,doctorname,doctorcode,titlecode,visitprice,clinicprice,otherprice,clinicaddress,status,staffintroduce,registername,timescope,timename,remark,hoscode,hosname,leixing) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24) RETURNING id"
		err = DBConn.db.QueryRow(sql, w.sequenceno, w.visitdate, w.timecode, w.starttime, w.endtime, w.deptcode, w.deptname, w.doctorsex, w.doctorname, w.doctorcode, w.titlecode, w.visitprice, w.clinicprice, w.otherprice, w.clinicaddress, w.status, w.staffintroduce, w.registername, w.timescope, w.timename, w.remark, w.hoscode, w.hosname, w.leixing).Scan(&w.id)
	}
	return err
}

func (w *menzhen_paiban) toPB() *pb.MenZhenPaiBan {
	v := &pb.MenZhenPaiBan{
		ID:             w.id,
		SEQUENCENO:     w.sequenceno,
		VISITDATE:      &tm.Timestamp{Seconds: w.visitdate},
		TIMECODE:       pb.TIMECODE1(w.timecode),
		TIMENAME:       w.timename,
		STARTTIME:      &tm.Timestamp{Seconds: w.starttime},
		ENDTIME:        &tm.Timestamp{Seconds: w.endtime},
		DEPTCODE:       w.deptcode,
		DEPTNAME:       w.deptname,
		DOCTORSEX:      pb.GENDER(w.doctorsex),
		DOCTORNAME:     w.doctorname,
		DOCTORCODE:     w.doctorcode,
		TITLECODE:      w.titlecode,
		VISITPRICE:     w.visitprice,
		CLINICPRICE:    w.clinicprice,
		OTHERPRICE:     w.otherprice,
		CLINICADDRESS:  w.clinicaddress,
		REMARK:         w.remark,
		STATUS:         w.status,
		STAFFINTRODUCE: w.staffintroduce,
		REGISTERNAME:   w.registername,
		TIMESCOPE:      w.timescope,
		HOSCODE:        w.hoscode,
		HOSNAME:        w.hosname,
		LEIXING:        pb.MenZhenPaiBan_PaiBanLeiXing(w.leixing),
	}
	return v
}

func (w *menzhen_paiban) fromPB(p *pb.MenZhenPaiBan) *menzhen_paiban {
	w.id = p.ID
	w.sequenceno = p.GetSEQUENCENO()
	w.timecode = int32(p.GetTIMECODE())
	w.starttime = p.GetSTARTTIME().GetSeconds()
	w.endtime = p.GetENDTIME().GetSeconds()
	w.deptcode = p.GetDEPTCODE()
	w.deptname = p.GetDEPTNAME()
	w.doctorsex = int32(p.GetDOCTORSEX())
	w.doctorname = p.GetDOCTORNAME()
	w.doctorcode = p.GetDOCTORCODE()
	w.titlecode = p.GetTITLECODE()
	w.visitprice = p.GetVISITPRICE()
	w.clinicprice = p.GetCLINICPRICE()
	w.otherprice = p.GetOTHERPRICE()
	w.clinicaddress = p.GetCLINICADDRESS()
	w.status = p.GetSTATUS()
	w.staffintroduce = p.GetSTAFFINTRODUCE()
	w.registername = p.GetREGISTERNAME()
	w.timescope = p.GetTIMESCOPE()
	w.timename = p.GetTIMENAME()
	w.remark = p.GetREMARK()
	w.hoscode = p.GetHOSCODE()
	w.hosname = p.GetHOSNAME()
	w.leixing = int32(p.GetLEIXING())
	return w
}
